function [textdensity, textcolumndensity, commentlineratio] = calctextdensity(text)
% CALCTEXTDENSITY Calculate text (source code)density metrics
%   TEXT cell array of strings
%   
%   NOTE Only the space character is considered whitespace.

stdlinelength = 80;
linecount = length(text);

whitespacecount = 0;
nonwhitespacecount = 0;
commentlinecount = 0;
textcolumndensity = zeros(1, stdlinelength);

% State value:
% 0 - default (whitespace or command)
% 1 - string, outside comment
% 2 - comment type 1 /*  */
% 3 - comment type 2 //
state = 0;

commenttype1flag = false;

for lineindex = 1:linecount
    line = text{lineindex};
    linelength = length(line);
    for columnindex = 1:linelength
        c = line(columnindex);

        % Switch state
        switch state
            case 0 % default
                if c == '"'
                    state = 1;
                elseif c == '/'
                    if columnindex + 1 <= linelength
                        if line(columnindex + 1) == '*'
                            state = 2;
                        elseif line(columnindex + 1) == '/'
                            state = 3;
                        end
                    end
                end
            case 1 % string
                if c == '"'
                    state = 0;
                end
            case 2 % comment type 1
                if c == '*'
                    if columnindex + 1 <= linelength
                        if line(columnindex + 1) == '/'
                            state = 0;
                        end
                    end
                end
            case 3 % comment type 2
                % on new line go to state 0
            otherwise
                disp('Invalid state');
        end
        
        % Calculate comment line count (type 1 comment)
        if state == 2
            if ~commenttype1flag
                commentlinecount = commentlinecount + 1;
                commenttype1flag = true;
            end
        end

        % Calculate text density
        if c == ' '
            whitespacecount = whitespacecount + 1;
        else
            nonwhitespacecount = nonwhitespacecount + 1;
        end

        % Calculate code column density
        if columnindex <= stdlinelength
            if c ~= ' '
                textcolumndensity(columnindex) = textcolumndensity(columnindex) + 1;
            end
        end
    end

    commenttype1flag = false;

    % Calculate comment line count (type 2 comment)
    if state == 3
        commentlinecount = commentlinecount + 1;
    end

    % Reset state set by type 2 comment
    if state == 3
        state = 0;
    end

    % 
    blankwhitespacecount = stdlinelength - linelength;
    if blankwhitespacecount > 0
        whitespacecount = whitespacecount + blankwhitespacecount;
    end
end

textdensity = nonwhitespacecount / (whitespacecount + nonwhitespacecount);

commentlineratio = commentlinecount / linecount;

textcolumndensity = textcolumndensity / linecount;
